package info.batcloud.fanli.core.service.impl;

import com.ctospace.archit.common.pagination.Paging;
import info.batcloud.fanli.core.domain.AgentApplyBO;
import info.batcloud.fanli.core.entity.*;
import info.batcloud.fanli.core.enums.AgentApplyStatus;
import info.batcloud.fanli.core.helper.PagingHelper;
import info.batcloud.fanli.core.repository.AgentApplyRepository;
import info.batcloud.fanli.core.repository.UserRepository;
import info.batcloud.fanli.core.service.AgentApplyService;
import info.batcloud.fanli.core.service.AgentService;
import info.batcloud.fanli.core.service.RegionService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.inject.Inject;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Predicate;
import java.util.List;

@Service
public class AgentApplyServiceImpl implements AgentApplyService {

    @Inject
    private UserRepository userRepository;

    @Inject
    private AgentApplyRepository agentApplyRepository;

    @Inject
    private AgentService agentService;

    @Inject
    private RegionService regionService;

    @Override
    public Paging<AgentApplyBO> search(SearchParam param) {
        Specification<AgentApply> specification = (root, query, cb) -> {
            Predicate predicate = cb.conjunction();
            List<Expression<Boolean>> expressions = predicate.getExpressions();

            if (StringUtils.isNotBlank(param.getPhone())) {
                expressions.add(cb.like(root.get("phone"), param.getPhone()));
            }
            if (param.getStatus() != null) {
                expressions.add(cb.equal(root.get("status"), param.getStatus()));
            } else {
            }
            return predicate;
        };
        Sort sort = new Sort(Sort.Direction.DESC, "id");
        Pageable pageable = new PageRequest(param.getPage() - 1,
                param.getPageSize(), sort);
        Page<AgentApply> page = agentApplyRepository.findAll(specification, pageable);
        return PagingHelper.of(page, item -> toAgentApply(item), param.getPage(), param.getPageSize());
    }

    @Override
    @Transactional
    public void verify(long id, AgentApplyStatus status) {
        AgentApply entity = agentApplyRepository.findOne(id);
        entity.setStatus(status);
        agentApplyRepository.save(entity);
    }

    private AgentApplyBO toAgentApply(AgentApply entity) {
        AgentApplyBO agent = new AgentApplyBO();
        BeanUtils.copyProperties(entity, agent);
        AgentApplyBO.User user = new AgentApplyBO.User();
        BeanUtils.copyProperties(entity.getUser(), user);
        agent.setUser(user);
        if(entity instanceof CityAgentApply) {
            CityAgentApply aa = (CityAgentApply) entity;
            Region city = regionService.findById(aa.getCityId());
            Region province = regionService.findById(city.getParentId());
            agent.setRegion(province.getName() + city.getName());
        } else if(entity instanceof DistrictAgentApply) {
            DistrictAgentApply agentApply = (DistrictAgentApply) entity;
            Region city = regionService.findById(agentApply.getCityId());
            Region district = regionService.findById(agentApply.getDistrictId());
            Region province = regionService.findById(city.getParentId());
            agent.setRegion(province.getName() + city.getName() + district.getName());
        }
        return agent;
    }
}
